package org.example.rowing.controller.util;

import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.event.*;
import javafx.stage.Window;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ConfigurableApplicationContext;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

@Slf4j
public class NavigationUtil {

    private static ConfigurableApplicationContext context;

    public static final Map<String, String> viewMap;

    static {
        viewMap = new HashMap<>();
        viewMap.put("btnEventInfo", "/fxml/rowingViews/EventInfoView.fxml");
        viewMap.put("btnCKEventInfo", "/fxml/canoeAndKayakViews/CKEventInfoView.fxml");
        viewMap.put("btnTeams", "/fxml/rowingViews/TeamInfoView.fxml");
        viewMap.put("btnCKTeams", "/fxml/canoeAndKayakViews/CKTeamInfoView.fxml");
        viewMap.put("btnRaceManagement", "/fxml/rowingViews/RaceInfoView.fxml");
        viewMap.put("btnCKRaceManagement", "/fxml/canoeAndKayakViews/CKRaceInfoView.fxml");
        viewMap.put("btnRegistration", "/fxml/rowingViews/RegistrationInfoView.fxml");
        viewMap.put("btnCKRegistration", "/fxml/canoeAndKayakViews/CKRegistrationInfoView.fxml");
        viewMap.put("btnResults", "/fxml/rowingViews/ResultsInfoView.fxml");
        viewMap.put("btnCKResults", "/fxml/canoeAndKayakViews/CKResultsInfoView.fxml");
        viewMap.put("btnHelp", "/fxml/rowingViews/HelpInfoView.fxml");
        viewMap.put("btnCKHelp", "/fxml/canoeAndKayakViews/CKHelpInfoView.fxml");
        viewMap.put("addEventButton", "/fxml/rowingViews/UpdateEventView.fxml");
        viewMap.put("addRaceButton", "/fxml/rowingViews/UpdateRaceView.fxml");
        viewMap.put("addCKRaceButton", "/fxml/canoeAndKayakViews/UpdateCKRaceView.fxml");
        viewMap.put("addTeamButton", "/fxml/rowingViews/UpdateTeamView.fxml");
        viewMap.put("addCKTeamButton", "/fxml/canoeAndKayakViews/UpdateCKTeamView.fxml");
        viewMap.put("addAthleteButton", "/fxml/rowingViews/UpdateAthleteView.fxml");
        viewMap.put("addCKAthleteButton", "/fxml/canoeAndKayakViews/UpdateCKAthleteView.fxml");
        viewMap.put("addRegistrationButton", "/fxml/rowingViews/UpdateRegistrationView.fxml");
        viewMap.put("addCKRegistrationButton", "/fxml/canoeAndKayakViews/UpdateCKRegistrationView.fxml");
        viewMap.put("addCKEventButton", "/fxml/canoeAndKayakViews/UpdateCKEventView.fxml");
        viewMap.put("exportChooseButton", "/fxml/rowingViews/ExportView.fxml");
        viewMap.put("exportCKChooseButton", "/fxml/canoeAndKayakViews/CKExportView.fxml");
        viewMap.put("exportLaneButton", "/fxml/LaneExportView.fxml");
    }

    /**
     * 获取spring的上下文
     * @param applicationContext
     */
    public static void setApplicationContext(ConfigurableApplicationContext applicationContext) {
        context = applicationContext;
    }

    public static ConfigurableApplicationContext getApplicationContext() {
        return context;
    }

    /**
     * 跳转到指定的FXML页面
     *
     * @param event  触发事件
     * @param fxmlFile  FXML文件路径
     * @param title  页面标题
     * @throws IOException
     */
    public static void navigateToScene(ActionEvent event, String fxmlFile, String title) throws IOException {
        FXMLLoader loader = new FXMLLoader(NavigationUtil.class.getResource(fxmlFile));
        // 将视图对应的控制器交给spring管理
        loader.setControllerFactory(context::getBean);
        Node node = loader.load();
        Parent root = (Parent) node;

        // 获取当前舞台（窗口）
        Stage stage = (Stage) ((javafx.scene.Node) event.getSource()).getScene().getWindow();

        // 获取当前 scene
        Scene previousScene = stage.getScene();

        // 保存 scene 的宽度和高度
        double sceneWidth = previousScene.getWidth();
        double sceneHeight = previousScene.getHeight();

        // 保存当前窗口状态
        boolean wasMaximized = stage.isMaximized();
        double width = stage.getWidth();
        double height = stage.getHeight();
        double x = stage.getX();
        double y = stage.getY();

        // 设置新场景到舞台
        Scene scene = new Scene(root, sceneWidth, sceneHeight);
        stage.setScene(scene);
        stage.setTitle(title);

        // 恢复窗口状态
        if (wasMaximized) {
            stage.setMaximized(true);
        } else {
            stage.setWidth(width);
            stage.setHeight(height);
            stage.setX(x);
            stage.setY(y);
        }
        stage.sizeToScene();
        stage.show();
    }

    public static void navigateToScene(Stage stage, String fxmlFile, String title) throws IOException {
        FXMLLoader loader = new FXMLLoader(NavigationUtil.class.getResource(fxmlFile));
        // 将视图对应的控制器交给spring管理
        loader.setControllerFactory(context::getBean);
        Node node = loader.load();
        Parent root = (Parent) node;

        // 获取当前 scene
        Scene previousScene = stage.getScene();

        // 保存 scene 的宽度和高度
        double sceneWidth = previousScene.getWidth();
        double sceneHeight = previousScene.getHeight();

        // 保存当前窗口状态
        boolean wasMaximized = stage.isMaximized();
        double width = stage.getWidth();
        double height = stage.getHeight();
        double x = stage.getX();
        double y = stage.getY();

        // 设置新场景到舞台
        Scene scene = new Scene(root, sceneWidth, sceneHeight);
        stage.setScene(scene);
        stage.setTitle(title);

        // 恢复窗口状态
        if (wasMaximized) {
            stage.setMaximized(true);
        } else {
            stage.setWidth(width);
            stage.setHeight(height);
            stage.setX(x);
            stage.setY(y);
        }
        stage.sizeToScene();
        stage.show();
    }

    public static void navigateToScene(Stage stage, String fxmlFile, String title, Consumer<Object> controllerInitializer) throws IOException {
        FXMLLoader loader = new FXMLLoader(NavigationUtil.class.getResource(fxmlFile));
        // 将视图对应的控制器交给spring管理
        loader.setControllerFactory(context::getBean);
        Node node = loader.load();
        Parent root = (Parent) node;

        // 初始化控制器
        Object controller = loader.getController();
        if (controllerInitializer != null && controller != null) {
            controllerInitializer.accept(controller);
        }

        // 获取当前 scene
        Scene previousScene = stage.getScene();

        // 保存 scene 的宽度和高度
        double sceneWidth = previousScene.getWidth();
        double sceneHeight = previousScene.getHeight();

        // 保存当前窗口状态
        boolean wasMaximized = stage.isMaximized();
        double width = stage.getWidth();
        double height = stage.getHeight();
        double x = stage.getX();
        double y = stage.getY();

        // 设置新场景到舞台
        Scene scene = new Scene(root, sceneWidth, sceneHeight);
        stage.setScene(scene);
        stage.setTitle(title);

        // 恢复窗口状态
        if (wasMaximized) {
            stage.setMaximized(true);
        } else {
            stage.setWidth(width);
            stage.setHeight(height);
            stage.setX(x);
            stage.setY(y);
        }
        stage.sizeToScene();
        stage.show();
    }

    /**
     * 显示一个通用的弹出框。
     *
     * @param fxmlPath  FXML文件路径
     * @param title     弹出框标题
     * @param owner     父窗口
     * @param controllerInitializer 初始化控制器的操作（使用Lambda表达式）
     */
    public static void showPopup(String fxmlPath, String title, Window owner, Consumer<Object> controllerInitializer) {
        try {
            // 加载FXML文件
            FXMLLoader loader = new FXMLLoader(NavigationUtil.class.getResource(fxmlPath));
            loader.setControllerFactory(context::getBean);
            Pane popupView = loader.load();

            // 初始化控制器
            Object controller = loader.getController();
            if (controllerInitializer != null && controller != null) {
                controllerInitializer.accept(controller);
            }

            // 创建弹出框舞台
            Stage stage = new Stage();
            stage.setResizable(false);
            stage.setTitle(title);
            stage.setScene(new Scene(popupView));
            stage.initModality(Modality.APPLICATION_MODAL); // 模态窗口
            stage.initOwner(owner); // 设置父窗口

            // 显示并等待关闭
            stage.showAndWait();
        } catch (IOException e) {
            log.error("加载弹出框失败: {}", fxmlPath, e);
        }
    }
}
